/*
 * ScenarioMethodInvoker.java
 * 
 * Created on 21.05.2007, 19:01:54
 * 
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package logrus.beanmock.invoker;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;


/**
 * 
 * @author serge
 */
public abstract class AbstractMethodInvoker implements MethodInvoker {

    private final Map<Method, Integer> statistics = new HashMap<Method, Integer>();

    protected abstract Object doInvoke(Object target, Method method, Object... args) throws Throwable;

    public MethodInvokerStatistics getStatistics() {
        return new MethodInvokerStatistics(Collections.unmodifiableMap(statistics));
    }

    public final Object invoke(Object target, Method method, Object... args) throws Throwable {
        registerInvocation(method);
        try {
            Object result = doInvoke(target, method, args);
            return result;
        } catch (Throwable e) {
            throw e;
        }
    }

    private void registerInvocation(final Method method) {
        Integer count = statistics.get(method);
        if (count != null) {
            count = Integer.valueOf(count.intValue() + 1);
        } else {
            count = Integer.valueOf(1);
        }
        statistics.put(method, count);
    }

}
